package pl.edu.agh.neuraleconomy.persistence.base;

import java.sql.SQLException;
import java.util.List;

import lombok.Getter;

import org.apache.log4j.Logger;

import pl.edu.agh.neuraleconomy.common.exception.ApplicationRuntimeException;
import pl.edu.agh.neuraleconomy.model.base.IModel;
import pl.edu.agh.neuraleconomy.persistence.utils.DBUtils;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;

public abstract class BaseDao<MODEL extends IModel> implements IDao<MODEL> {
	protected Logger logger = Logger.getLogger(getClass());
	
	@Getter
	protected Dao<MODEL, Long> dao;
	
	public BaseDao(Class<? extends MODEL> clazz){
		try {
			dao = DaoManager.createDao(DBUtils.getConnectionSource(), clazz);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public List<MODEL> getAll(){
		try {
			return dao.queryForAll();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public MODEL getById(Long id){
		try {
			return dao.queryForId(id);
		} catch (SQLException e) {
			logger.error("Nie udalo sie odczytac obiektu o id " + id, e);
			throw new ApplicationRuntimeException(e);
		}
	}
	
	@Override
	public void create(MODEL model){
		try {
			dao.create(model);
		} catch (SQLException e) {
			logger.error("Nie udalo sie zapisac obiektu do bazy danych", e);
			throw new ApplicationRuntimeException(e);
		}
	}
	
	@Override
	public void save(MODEL model){
		try {
			if(model.getId() != null){
				dao.update(model);
			}else{
				dao.create(model);
			}
		} catch (SQLException e) {
			logger.error("Nie udalo sie zapisac obiektu do bazy danych", e);
			throw new ApplicationRuntimeException(e);
		}
	}
	
	@Override
	public void tryDelete(MODEL model){
		try{
			if(model.getId() != null){
				dao.delete(model);
			}
		} catch (SQLException e){
			logger.error("Nie udalo sie usunac obiektu z bazy danych", e);
			throw new ApplicationRuntimeException(e);
		}
	}
	
	protected MODEL getFirst(List<MODEL> resultList){
		if(resultList!=null && resultList.size()>0){
			return resultList.get(0);
		}
		return null;
	}
}
